// 引入bcrypt
const bcrypt = require("bcrypt");
const { json } = require("express");

// 导入用户模块
const { User } = require("../model/user")
const { Question } = require("../model/questions")
const { Answer } = require("../model/answers")

// 注册用户
exports.register = async (req, res, next) => {
  try {
    let { email, password, name } = req.validValue
    // 1.查询邮箱是否已经被注册过了
    let user = await User.findOne({ email })
    // 2.如果注册了，我们就不能再次注册，直接返回失败的响应
    if(user) {
      return res.status(400).json({
        code: 400,
        msg: "邮箱已经被注册了,请重新输入", 
        data: { email }
      })
    } 
    // 3.如果没有注册过，我们就进行注册，返回成功的响应
    // 3.1 加密
    const salt = await bcrypt.genSalt(10);
    password = await bcrypt.hash(password, salt);
    // 3.2 创建 User 实例
    user = new User({
      email,
      password,
      name
    })
    // 3.3 进行数据的存储
    await user.save();
    // 3.4 成功的响应
    res.status(200).json({
      code: 200,
      msg: "注册成功",
      data: { email }
    })
  } catch (err) {
    next(err)
  } 
}; 

// 获取所有用户
exports.getUserList = async (req, res, next) => {
  try {
    // 1.查询用户
    let userList = await User.find();
    // 2.如果不存在，返回失败的响应
    if(!userList)  return res.status(400).json({
      code: 400,
      msg: "用户列表不存在"
    })
    // 3.如果存在，返回成功的响应
    res.status(200).json({
      code: 200,
      msg: "用户列表查询成功",
      data: { userList }
    })
  } catch (err) {
    next(err)
  }
};

// 获取指定用户
exports.getUser =  async(req, res, next) => {
  try {
    const { fields = '' } = req.query;
    const selectFields = fields.split(';').filter(f => f).map(f => ' +' + f).join('');

    const populateStr = fields.split(";").filter(f => f).map(f => {
      if(f == "employments") {
        return 'employments.company employments.job'
      }
      if(f == "educations"){
        return "educations.school educations.major"
      }
      return f;
    }).join(" ")

    let userId = req.params.id
    let user = await User.findById(userId).select(selectFields).populate(populateStr)

    if(!user)  return res.status(400).json({
      code: 400,
      msg: "该用户不存在"
    })

    res.status(200).json({
      code: 200,
      msg: "查询指定用户成功",
      data: { user }
    })
  } catch (err) {
    next(err)
  }
};

// 编辑/修改指定用户
exports.updateUser = async (req, res, next) => {
  try {
    let userId = req.params.id
    let body = req.body
    console.log(body.password);
    const salt = await bcrypt.genSalt(10);
    body.password = await bcrypt.hash(body.password, salt);
    console.log(body.password);

    // 1.查询用户并修改
    const data = await User.findByIdAndUpdate(userId, body)
    // 2.更新失败
    if(!data) res.status(400).json({
      code: 400,
      msg: "更新用户失败"
    })
    // 3.更新成功
    res.status(200).json({
      code: 200,
      msg: "更新成功",
      data: { body }
    })
  } catch (err) {
    next(err)
  }
};

// 删除指定用户
exports.deleteUser = async (req, res, next) => {
  try {
    let userId = req.params.id
    // 查找用户数据并删除
    const data = await User.findByIdAndDelete(userId)

    // 查询失败
    if(!data) {
      return res.status(400).json({
        code: 400,
        msg: "删除用户失败",
        value: {
          _id: userId
        }
      })
    }

    // 查询成功
    const body = req.body
    res.status(200).json({
      code: 200,
      msg: "删除用户成功",
      data: { body }
    })

  } catch (err) {
    next(err);
  }
};

// 获取关注列表
exports.listFollowing = async (req, res, next) => {
  try{
    let userId = req.params.id;
    const user = await User.findById(userId).select("+following").populate("following")
    // 未找到
    if(!user) return res.status(400).json({
      code: 400,
      msg: "获取关注列表失败"
    })
    // 获取成功
    res.status(200).json({
      code: 200,
      msg: "获取关注列表成功",
      data: user
    })
  }catch(err) {
    next(err)
  }
}

// 关注
exports.follow = async (req, res ,next) => {
  try{
    let userId = req.userData._id
    const user = await User.findById(userId.toString()).select("+following")
    // 如果已经关注过了，那我们就直接return
    if(user.following.map(id => id.toString()).includes(req.params.id)) return res.status(400).json({
      code: 400,
      msg: "已关注,关注失败"
    })
    // 如果之前没用关注过，那我们再关注
    user.following.push(req.params.id)
    await user.save()
    res.status(200).json({
      code: 200,
      msg: "关注成功",
      data: user
    })
  }catch(err) {
    next(err)
  }
}

// 取消关注
exports.unfollow = async (req, res ,next) => {
  try{
    let userId = req.userData._id
    const user = await User.findById(userId.toString()).select("+following")
    // 获取所关注的用户的索引
    const index = user.following.map(id => id.toString()).indexOf(req.params.id)
    // 若没有关注，则取消关注
    if(index == -1) return res.status(400).json({
      code: 400,
      msg: "未关注,取消关注失败"
    })

    // 已经关注，就进行取消操作
    user.following.splice(index, 1);
    await user.save()
    res.status(200).json({
      code: 200,
      msg: "取消关注成功"
    })
  }catch(err) {
    next(err)
  }
}

// 获取某个用户的粉丝列表
exports.listFollowers = async (req, res, next) => {
  try{
    const users = await User.find({ following: req.params.id })
    if(!users) return res.status(400).json({
      code: 400,
      msg: "查询粉丝列表失败"
    })
    res.status(200).json({
      code: 200,
      msg: "查询粉丝列表成功",
      data: users
    })
  }catch(err) {
    next(err)
  }
}

// 关注话题
exports.followTopic = async (req, res ,next) => {
  try{
    let userId = req.userData._id
    const user = await User.findById(userId.toString()).select("+followingTopic")
    // 如果已经关注过了，那我们就直接return
    if(user.followingTopic.map(id => id.toString()).includes(req.params.id)) return res.status(400).json({
      code: 400,
      msg: "已关注,关注失败"
    })
    // 如果之前没用关注过，那我们再关注
    user.followingTopic.push(req.params.id)
    await user.save()
    res.status(200).json({
      code: 200,
      msg: "关注成功",
      data: user
    })
  }catch(err) {
    next(err)
  }
}

// 取消关注话题
exports.unfollowTopic = async (req, res ,next) => {
  try{
    let userId = req.userData._id
    const user = await User.findById(userId.toString()).select("+followingTopic")
    // 获取所关注的用户的索引
    const index = user.followingTopic.map(id => id.toString()).indexOf(req.params.id)
    // 若没有关注，则取消关注
    if(index == -1) return res.status(400).json({
      code: 400,
      msg: "未关注,取消关注失败"
    })

    // 已经关注，就进行取消操作
    user.followingTopic.splice(index, 1);
    await user.save()
    res.status(200).json({
      code: 200,
      msg: "取消关注成功"
    })
  }catch(err) {
    next(err)
  }
}

// 获取用户关注话题列表
exports.listFollowingTopic = async (req, res, next) => {
  try{
    let userId = req.params.id;
    const user = await User.findById(userId).select("+followingTopic").populate("followingTopic")
    if(!user) return res.status(400).json({
      code: 400,
      msg: "查询失败"
    })
    res.status(200).json({
      code: 200,
      msg: "查询成功",
      data:  user 
    })
  } catch(err) {
    next(err)
  }
};

// 用户的问题列表
exports.listQuestions = async (req, res, next) => {
  try{
    const questions = await Question.find({ questioner: req.params.id })
    if(!questions) return res.status(400).json({
      code: 400,
      msg: "查询失败"
    })

    res.status(200).json({
      code: 200,
      msg: "查询成功",
      data: questions
    })
  }
  catch(err) {
    next(err)
  }
}

/*
  赞的
 */
// 喜欢答案
exports.likeAnswer = async (req, res, next) => {
  try{
    let userId = req.userData._id
    const user = await User.findById(userId.toString()).select("+likingAnswers")
    if(!user.likingAnswers.map(id => id.toString()).includes(req.params.id)){
      user.likingAnswers.push(req.params.id)
      await user.save()
      await Answer.findByIdAndUpdate(req.params.id, { $inc: {voteCount: 1} })
    }
    // res.status(200).json({
    //   code: 200,
    //   msg: "操作成功",
    //   data: user
    // })
    next()
  }catch(err) {
    next(err)
  }
}


// 取消喜欢
exports.unlikeAnswer = async (req, res ,next) => {
  try{
    let userId = req.userData._id
    const user = await User.findById(userId.toString()).select("+likingAnswers")
    const index = user.likingAnswers.map(id => id.toString()).indexOf(req.params.id)
    if(index > -1) {
      user.likingAnswers.splice(index, 1);
      await user.save()
      await Answer.findByIdAndUpdate(req.params.id, { $inc: {voteCount: -1} })
    }
    res.status(200).json({
      code: 200,
      msg: "取消赞成功"
    })
  }catch(err) {
    next(err)
  }
}

// 喜欢的答案列表
exports.listLikingAnswers = async (req, res, next) => {
  try{
    let userId = req.params.id;
    const user = await User.findById(userId).select("+likingAnswers").populate("likingAnswers")
    if(!user) return res.status(400).json({
      code: 400,
      msg: "操作失败"
    })
    res.status(200).json({
      code: 200,
      msg: "操作成功",
      data:  user 
    })
  } catch(err) {
    next(err)
  }
};

/* 
  踩的
*/
// 不喜欢答案
exports.dislikeAnswer = async (req, res ,next) => {
  try{
    let userId = req.userData._id
    const user = await User.findById(userId.toString()).select("+dislikingAnswers")
    if(!user.dislikingAnswers.map(id => id.toString()).includes(req.params.id)) {
      user.dislikingAnswers.push(req.params.id)
      await user.save()
    }
    // res.status(200).json({
    //   code: 200,
    //   msg: "操作成功",
    //   data: user
    // })
    next()
  }catch(err) {
    next(err)
  }
}

// 取消不喜欢
exports.undislikeAnswer = async (req, res ,next) => {
  try{
    let userId = req.userData._id
    const user = await User.findById(userId.toString()).select("+dislikingAnswers")
    const index = user.dislikingAnswers.map(id => id.toString()).indexOf(req.params.id)
    if(index > -1) {
      user.dislikingAnswers.splice(index, 1);
      await user.save()
    }
    res.status(200).json({
      code: 200,
      msg: "操作成功"
    })
  }catch(err) {
    next(err)
  }
}

// 不喜欢的答案列表
exports.listDisLikingAnswers = async (req, res, next) => {
  try{
    let userId = req.params.id;
    const user = await User.findById(userId).select("+dislikingAnswers").populate("dislikingAnswers")
    if(!user) return res.status(400).json({
      code: 400,
      msg: "操作失败"
    })
    res.status(200).json({
      code: 200,
      msg: "操作成功",
      data:  user 
    })
  } catch(err) {
    next(err)
  }
};


// 收藏答案
exports.collectingAnswer = async (req, res ,next) => {
  try{
    let userId = req.userData._id
    const user = await User.findById(userId.toString()).select("+collectingAnswers")
    if(user.collectingAnswers.map(id => id.toString()).includes(req.params.id)) return res.status(400).json({
      code: 400,
      msg: "已收藏,收藏失败"
    })
    user.collectingAnswers.push(req.params.id)
    await user.save()
    res.status(200).json({
      code: 200,
      msg: "收藏成功",
      data: user
    })
  }catch(err) {
    next(err)
  }
}

// 取消收藏
exports.uncollectingAnswer = async (req, res ,next) => {
  try{
    let userId = req.userData._id
    const user = await User.findById(userId.toString()).select("+collectingAnswers")
    const index = user.collectingAnswers.map(id => id.toString()).indexOf(req.params.id)
    if(index == -1) return res.status(400).json({
      code: 400,
      msg: "未收藏,取消收藏失败"
    })

    user.collectingAnswers.splice(index, 1);
    await user.save()
    res.status(200).json({
      code: 200,
      msg: "取消收藏成功"
    })
  }catch(err) {
    next(err)
  }
}

// 获取收藏列表
exports.listCollectingAnswers = async (req, res, next) => {
  try{
    let userId = req.params.id;
    const user = await User.findById(userId).select("+collectingAnswers").populate("collectingAnswers")
    if(!user) return res.status(400).json({
      code: 400,
      msg: "操作失败"
    })
    res.status(200).json({
      code: 200,
      msg: "操作成功",
      data:  user 
    })
  } catch(err) {
    next(err)
  }
};
